package com.fubowen.reader.ui.fragment

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import com.fubowen.reader.databinding.PublicNoPermissionBinding
import com.fubowen.reader.db.model.PermissionState
import com.fubowen.reader.extension.setVisible
import com.fubowen.reader.vm.PermissionViewModel
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.launch

const val MANAGE_EXTERNAL_STORAGE = "MANAGE_EXTERNAL_STORAGE"

abstract class PermissionFragment : BottomSheetDialogFragment() {

    private lateinit var binding: PublicNoPermissionBinding
    private lateinit var intentLauncher: ActivityResultLauncher<Intent>
    open val permissionViewModel by activityViewModels<PermissionViewModel>()
    open val pagePermission = mutableMapOf<String, String>()

    //region 生命周期
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        intentLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            permissionViewModel.changePermission(MANAGE_EXTERNAL_STORAGE, MANAGE_EXTERNAL_STORAGE())
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = PublicNoPermissionBinding.inflate(inflater)
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if (pagePermission.isNotEmpty()) {
            lifecycleScope.launch {
                permissionViewModel.permissionFlow.collect { onChangedPermission(it) }
            }
            if (view is ViewGroup) {
                view.addView(binding.root)
                binding.noPermissionRequest.setOnClickListener {
                    onRequestPermission()
                }
            }
            initPermission()
        }
    }

    //endregion

    private fun MANAGE_EXTERNAL_STORAGE() = when {
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> if (Environment.isExternalStorageManager()) PackageManager.PERMISSION_GRANTED else PackageManager.PERMISSION_DENIED
        else -> ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE)
    }

    private fun initPermission() {
        val builder = StringBuilder()
        for ((permission, description) in pagePermission) {
            when (permission) {
                MANAGE_EXTERNAL_STORAGE -> {
                    permissionViewModel.changePermission(MANAGE_EXTERNAL_STORAGE, MANAGE_EXTERNAL_STORAGE())
                    builder.appendLine(description)
                }
            }
        }
        binding.noPermissionDescription.text = builder
    }

    open fun onRequestPermission() {
        for ((permission, _) in pagePermission) {
            when (permission) {
                MANAGE_EXTERNAL_STORAGE -> {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                        val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                        intent.data = Uri.parse("package:" + requireContext().packageName)
                        intentLauncher.launch(intent)
                    }
                }
            }
        }
    }

    open fun onChangedPermission(state: PermissionState) {
        if (state.state == PackageManager.PERMISSION_GRANTED) {
            binding.root.setVisible(false)
        }
    }
}

